<template>
  <div :style="{backgroundImage:`url(${computer})`}" class="computer">
    <div v-if="audioList.length > 0" :style="getThemeStyle()" class='music-container' @error="()=>console.log('图片加载失败')">
      <div class="music-mask"></div>
      <div :style="[{'width':isListCollapse ? '0' : '32%'},{'opacity':isListCollapse ? '0' : '1'}]" class="music-list">
        <div class="music-list-title">播放列表 <span class="music-list-length">{{ audioList.length }}</span></div>
        <div class="music-list-container">
          <div v-for="(item,index) in audioList" :key="index" :style="{background: audioIndex === index ? '#edeeef' : ''}" class="music-list-item" @click="handleSwitchSong(index)">
            <div class="music-list-item-left">
              <img :src="item.imgUrl || defaultSongImg" alt="">
              <div class="song-information">
                <span class="item-name">{{ item.name }}</span>
                <span class="item-singer">{{ item.singer }}</span>
              </div>
            </div>
            <div class="music-list-item-right"></div>
            <div v-show="audioIndex === index" :style="[{backgroundColor:`rgba(${themeColorList.deepestColor},.5)`},{width:`${progress}%`}]" class="list-item-progress"></div>
          </div>
        </div>
      </div>
      <div class="music-top">
        <div class="music-top-left">
          <!--          <i class="iconfont icon-wangyesuoxiao" @click="goToFullScreen"></i>-->
        </div>
        <div class="music-top-right">
          <div class="switch-theme-container">
            <button class="switch-theme-button" @click="handleSwitchTheme">{{ switchThemeIndex === 1 ? "渐变背景" : "封面背景" }}</button>
          </div>
        </div>
      </div>
      <div class="music-main" @click="isListCollapse = true">
        <div class="music-main-left">
          <div :class="[isPlaying ? 'record-img-rotate' : '']" :style="[{backgroundImage:`url(${audioList[audioIndex].imgUrl || defaultSongImg})`}]" class="record-img">
            <div :style="[{backgroundImage:`url(${disc})`}]" class="music-main-record">
            </div>
          </div>
          <div :style="{backgroundImage: `url(${stylusCircle})`}" class="stylus-container">
          </div>
          <img :style="[{transform: `rotate(${isPlaying ? 42 : 0}deg)`}]" alt="加载失败" class="stylus" src="@/assets/images/stylus.png"/>
        </div>
        <div class="music-main-right">
          <div class="music-main-song-information">
            <h3>{{ audioList[audioIndex].name }}</h3>
            <span class="song-name">{{ audioList[audioIndex].singer }}</span>
          </div>
          <div ref="musicLyric" class="music-lyric">
            <div :style="{'transform':`translateY(${musicLyricTranslate}px)`}" class="lyric-item-container">
              <div v-for="(lyric, index) in lyrics"
                   :key="index"
                   :class="{ 'lyric-active': lyrics.length === 1 || (currentTime >= lyric.timestamp && currentTime < lyrics[index + 1]?.timestamp) }"
                   class="lyric-item">
                {{ lyric.content }}
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="music-bottom">
        <div class="progress-container" @click="handleProgressPosition">
          <div :style="[{width:`${progress}%`}]" class="progress">
            <div class="dot" style="pointer-events: none;"></div>
          </div>
        </div>
        <div class="music-bottom-left">
          <i class="iconfont icon-xiazai" @click="downloadFile(audioList[audioIndex].audioUrl)"></i>
          <span class="audio-time">{{ currentTime + ' / ' + (duration || '歌曲加载中....') }}</span>
        </div>
        <div class="music-bottom-main">
          <i class="iconfont icon-aixin"></i>
          <i class="iconfont icon-yinxiang-shangyiqu" @click="handleSwitchTrack('previous')"></i>
          <i :class="[isPlaying ? 'icon-zantingbofang' : 'icon-zantingbofang1']" class="iconfont  pause" @click="handlePlayPause"></i>
          <i class="iconfont icon-yinxiang-xiayiqu" @click="handleSwitchTrack('next')"></i>
          <i :class="getPlayModeIconClass()" class="iconfont " @click="handlePlayMode"></i>
        </div>
        <div class="music-bottom-right">
          <i class="iconfont icon-liebiao" @click="isListCollapse = !isListCollapse"></i>
          <i class="iconfont icon-shengyin"></i>
          <div class="volume-container" @click="handleVolumePosition">
            <div :style="{width:`${volume}%`}" class="volume">
              <div class="dot" style="pointer-events: none;"></div>
            </div>
          </div>
        </div>
      </div>
      <audio ref="audio" :src="audioList[audioIndex].audioUrl" preload="auto" @ended="changePlayMode" @error="handleError"></audio>
    </div>
  </div>
</template>

<script lang="ts" setup>
import {nextTick, onMounted, ref, Ref, watch, watchEffect} from 'vue';
import {getMusicData} from '@/api/request';
import {getAssetsFile, findDeepestAndLightest, throttle} from "@/utils/util";
import themeColor from "@/utils/colorExtraction"
import {useRouter} from 'vue-router'
import showMessage from "@/components/Message/index"

// 路由
const router = useRouter()
// 电脑背景图片
const computer = getAssetsFile("images/computer.png")
// 唱片机图片资源
const stylusCircle = getAssetsFile("images/stylus-circle.png")
// 获取默认歌曲图片资源
const defaultSongImg = getAssetsFile("images/default-song-img.jpg")
// 唱片圆盘图片
const disc = getAssetsFile("images/disc.png");
// 歌曲列表
let audioList: Ref<MusicData[]> = ref([]);
// 当前播放歌曲的索引
const audioIndex = ref(0);
// 是否收起歌曲列表
const isListCollapse = ref(true);
// 歌词数据
const lyrics = ref<Lyric[]>([]);
// 处理歌曲高度索引
const prevNumber = ref(-1);
// 播放模式 1列表循环 2单曲循环 3随机播放
const playMode: Ref<number> = ref(1);
// 主题模式 1封面 2颜色
const switchThemeIndex = ref(2);
// 初始进度
const progress = ref(1);
// 音量
const volume: Ref<number> = ref(0);
// 避免重复设置音量
const oneVolume: Ref<boolean> = ref(true);
// 是否全屏
const isFullScreen = ref(false);
// 获取audio dom
const audio: any = ref<HTMLAudioElement | null>(null);
// 播放状态
const isPlaying: any = ref(false);
// 歌词进度
const musicLyricTranslate = ref(0);
// 原始歌词进度
const originalMusicLyricTranslate = ref(0);
// 音频总时长
const duration = ref();
// 当前播放时间
const currentTime = ref();
// 时长
const originalTime = ref();
// 原始音频时长
const originalDurationTime = ref();
// 消息提示定时器ID
let timeoutId: NodeJS.Timeout | null = null;

// 定义歌词接口
interface Lyric {
  timestamp: string, // 时间戳
  content: string // 歌词内容
}

// 定义颜色信息接口
const themeColorList: Ref<ColorInfo> = ref<ColorInfo>({
  deepestColor: [0, 0, 0], // 最深的颜色
  lightestColor: [255, 255, 255] // 最浅的颜色
});

// 定义颜色信息类型
type ColorInfo = {
  deepestColor: [number, number, number]; // 最深的颜色值
  lightestColor: [number, number, number]; // 最浅的颜色值
};

// 定义音乐数据接口
interface MusicData {
  name: string; // 音乐名称
  audioUrl: string; // 音频地址
  imgUrl: string; // 图片地址
  singer: string; // 歌手
  lyrics: string // 歌词
}

// 定义音乐数据响应接口
interface MusicDataResponse {
  data: MusicData[]; // 音乐数据数组
}

watch(() =>
        router.currentRoute.value.path,
    (toPath) => {
      //要执行的方法
      if (toPath === "/music") {
        const play = window.sessionStorage.getItem("play") === "true"
        if (play) {
          handlePlayPause()
        }
        // 添加一个事件监听器，当按键按下时触发
        document.addEventListener("keydown", handleSpace);
      } else {
        window.sessionStorage.setItem("play", isPlaying.value)
        isPlaying.value = false
        // 添加一个事件监听器，当按键按下时触发
        document.removeEventListener("keydown", handleSpace);
      }
    }, {immediate: true, deep: true})

// 获取音乐数据
onMounted(async () => {
  getMusicData().then((res: MusicDataResponse) => {
    audioList.value = res.data
  })
  document.addEventListener('fullscreenchange', handleFullScreenChange);
});


function handleSpace(event: KeyboardEvent) {
  // 如果按下的键是空格键，执行相应操作
  if (event.code === "Space") {
    if (duration.value) {
      handlePlayPause()
    }
  }
}

// 使用节流函数处理播放模式切换
const handlePlayMode = throttle(() => {
  if (playMode.value === 3) {
    playMode.value = 1;
  } else {
    playMode.value++;
  }
  showMessage(`当前播放模式：${playMode.value === 1 ? '列表播放' : playMode.value === 2 ? '单曲循环' : '随机播放'}`, "success")
}, 500)

// 获取播放模式的图标类名
function getPlayModeIconClass() {
  switch (playMode.value) {
    case 1:
      return 'icon-liebiaoxunhuan';
    case 2:
      return 'icon-loop';
    case 3:
      return 'icon-suijibofang';
    default:
      return '';
  }
}

// 切换播放模式
const changePlayMode = () => {
  if (playMode.value === 1) {
    switchTrack("next"); // 下一首
  } else if (playMode.value === 2) {
    switchTrack("single-loop"); // 单曲循环
  } else {
    switchTrack("random-play"); // 随机播放
  }
}

// 切换播放模式
const handleSwitchTrack = throttle((type: string) => {
  if (playMode.value === 1) {
    switchTrack(type); // 列表循环模式下切换音轨
  } else if (playMode.value === 2) {
    switchTrack("single-loop"); // 单曲循环模式下切换音轨
  } else {
    switchTrack("random-play"); // 随机播放模式下切换音轨
  }
}, 500)

// 使用节流函数处理主题切换
const handleSwitchTheme = throttle(() => {
  switchThemeIndex.value = switchThemeIndex.value === 1 ? 2 : 1; // 切换主题模式
}, 500)

// 获取主题样式
const getThemeStyle = () => {
  if (switchThemeIndex.value === 1) {
    let backgroundImage: string;
    if (audioList.value[audioIndex.value].imgUrl !== "") {
      backgroundImage = `url(${audioList.value[audioIndex.value].imgUrl})`; // 使用音频封面图作为背景图
    } else {
      backgroundImage = `url(${defaultSongImg})`; // 使用默认音频封面图作为背景图
    }
    return {backgroundImage: backgroundImage}; // 返回背景图样式
  } else {
    return {backgroundImage: `linear-gradient(to bottom, rgb(${themeColorList.value.deepestColor}), rgb(${themeColorList.value.lightestColor})`} // 返回渐变背景样式
  }
}

// 处理进度条百分比
function calculatePercentage(duration: number, currentTime: number) {
  if (duration <= 0) {
    return 0; // 避免除以零错误
  }
  return (Math.floor(currentTime) / Math.floor(duration)) * 100;
}

// 计算出歌曲应该播放的进度
function handleProgressPosition(e: MouseEvent) {
  // 获取点击位置相对于元素左侧的距离
  const rect = (e.target as HTMLElement).getBoundingClientRect();
  const offsetXFromLeft = e.clientX - rect.left;
  // 获取dom宽度
  const width: HTMLDivElement | null = document.querySelector(".progress-container")
  if (width) {
    // 计算百分比
    const percent = (offsetXFromLeft / width.clientWidth) * 100;
    if (originalDurationTime.value && audio.value) {
      audio.value.currentTime = originalDurationTime.value * (percent / 100);
    }
  }
}

// 列表切歌
const handleSwitchSong = throttle((index: number) => {
  if (audioIndex.value !== index) audioIndex.value = index
  isPlaying.value = false
  togglePlayPause()
}, 300)


// 处理音量位置
function handleVolumePosition(e: MouseEvent) {
  // 获取点击位置相对于元素左侧的距离
  const rect = (e.target as HTMLElement).getBoundingClientRect();
  const offsetXFromLeft = e.clientX - rect.left;
  // 获取dom宽度
  const width: HTMLDivElement | null = document.querySelector(".volume-container")
  if (width) {
    // 计算百分比
    const percent = (offsetXFromLeft / width.clientWidth) * 100;
    if (audio.value) {
      volume.value = Math.round(percent)
      if (volume.value >= 97) {
        volume.value = 100
      }
      showMessage(`当前音量：${volume.value}%`, "success")
      const newVolume = percent / 100
      audio.value.volume = newVolume.toFixed(1)
    }
  }
}


// 进入全屏模式的函数
function goToFullScreen() {
  const element: any = document.querySelector('.music-container');
  if (element) {
    if (element.requestFullscreen) {
      element.requestFullscreen();
    } else if (element.webkitRequestFullscreen) { // Safari
      element.webkitRequestFullscreen();
    } else if (element.msRequestFullscreen) { // IE11
      element.msRequestFullscreen();
    }
  }
}

// 全屏变化事件处理函数
const handleFullScreenChange = () => {
  isFullScreen.value = !!document.fullscreenElement
}

/**
 * 解析歌词数据的函数
 * @param data 包含歌词信息的字符串
 * @returns 解析后的歌词数组
 */
function parseData(data: string): Lyric[] {
  if (!data) {
    return [{"timestamp": "00:00.000", "content": "暂无歌词"}]
  }
  const pattern = /\[(\d+:\d+\.\d+)\](.+)/;
  const lines = data.split('\n');
  return lines.map(line => {
    const match = line.match(pattern);
    if (match) {
      const timestamp = match[1];
      const content = match[2].trim();
      return {"timestamp": timestamp, "content": content};
    } else {
      return null;
    }
  }).filter((item): item is Lyric => item !== null);
}

/**
 * 设置颜色方法
 */
const SetColor = (colorArr: any[]) => {
  // 初始化删除多余子节点
  if (colorArr.length > 0) {
    themeColorList.value = findDeepestAndLightest(colorArr)
  }
}

// 播放暂停控制
function handlePlayPause() {
  const audioElement = audio.value; // 获取音频元素
  // 如果音频正在播放，则暂停；如果暂停中，则播放
  if (audioElement.paused) {
    audioElement.play();
    isPlaying.value = true;
  } else {
    audioElement.pause();
    isPlaying.value = false;
  }
}

// 播放暂停控制
function togglePlayPause() {
  // 获取音频元素
  const audioElement = audio.value;

  function handleCanplay() {
    if (audioElement.paused) {
      audioElement.play();
      isPlaying.value = true;
    } else {
      audioElement.pause();
      isPlaying.value = false;
    }
    // 移除 canplay 事件监听器
    audioElement.removeEventListener('canplay', handleCanplay);
  }

  // 创建 canplay 事件监听器
  audioElement.addEventListener('canplay', handleCanplay);
}

// 切换歌曲
const switchTrack = (direction: string) => {
  if (direction === 'previous') {
    duration.value = null
    audioIndex.value = (audioIndex.value - 1 + audioList.value.length) % audioList.value.length;
  } else if (direction === 'next') {
    audioIndex.value = (audioIndex.value + 1) % audioList.value.length;
  } else if (direction === 'single-loop') {
    const dom = audio.value;
    dom.currentTime = 0;
    dom.play();
    return
  } else if (direction === 'random-play') {
    duration.value = null
    audioIndex.value = Math.floor(Math.random() * audioList.value.length);
  }
  isPlaying.value = false;
  togglePlayPause(); // 音频已准备就绪，可以播放
};

// 处理播放错误，自动播放下一首歌曲
function handleError(errorEvent: any) {
  showMessage('歌曲播放失败，即将自动播放下一首歌曲', 'success')
  switchTrack('next');
  setTimeout(() => {
    handlePlayPause()
  }, 3000)
}

// 格式化歌曲时间
function formatTime(seconds: number) {
  // 获取分钟和秒数
  const minutes = Math.floor(seconds / 60);
  const remainingSeconds = Math.round(seconds % 60); // 四舍五入
  // 将分钟和秒数转换为两位数格式
  const formattedMinutes = String(minutes).padStart(2, '0');
  const formattedSeconds = String(remainingSeconds).padStart(2, '0');
  // 返回格式化后的时间
  return `${formattedMinutes}:${formattedSeconds}`;
}


// 使用 watchEffect 监听音频数据、音频元素和当前索引的变化
watchEffect(() => {
  const audioElement = audio.value; // 获取音频元素
  const currentIndex = audioIndex.value; // 获取当前索引
  // 确保音频列表不为空且音频元素存在
  if (audioList.value.length > 0 && audioElement) {
    // 如果音量为单一值，则设置音频音量为 0.5，并更新音量百分比，并将 oneVolume 的值设置为 false
    if (oneVolume.value) {
      audio.value.volume = 0.5;
      volume.value = (audio.value.volume * 100);
      oneVolume.value = false;
    }
    // 设置音频地址并加载音频
    audioElement.src = audioList.value[currentIndex].audioUrl;
    audioElement.load();
    // 解析歌词数据并更新歌词
    lyrics.value = parseData(audioList.value[audioIndex.value].lyrics);
    // 创建图片对象并设置跨域属性
    const img = new Image();
    if (audioList.value[currentIndex].imgUrl !== "") {
      img.src = audioList.value[currentIndex].imgUrl;
    } else {
      img.src = defaultSongImg;
    }
    img.crossOrigin = 'anonymous';
    // 图片加载完成后调用 themeColor 函数
    img.onload = () => {
      themeColor(50, img, 20, SetColor);
    };
    // 使用 nextTick 确保 DOM 更新完毕后执行操作
    nextTick(() => {
      if (lyrics.value) {
        prevNumber.value = -1; // 重置 prevNumber
        const lyricContainer = document.querySelector(".music-lyric");
        const lyricItem = document.querySelector(".lyric-item");
        // 计算歌词容器和歌词项的垂直居中位置
        if (lyricContainer && lyricItem) {
          musicLyricTranslate.value = lyricContainer.clientHeight / 2 - lyricItem.clientHeight / 2;
          originalMusicLyricTranslate.value = musicLyricTranslate.value;
        }
      }
    })
  }
});


// 监听音频时长和当前播放时间的变化
watchEffect(() => {
  const audioElement = audio.value;
  if (audioElement) {
    audioElement.addEventListener('loadedmetadata', () => {
      // 更新音频时长
      duration.value = formatTime(audioElement.duration);
      originalDurationTime.value = audioElement.duration;
    });
    audioElement.addEventListener('timeupdate', () => {
      // 更新当前播放时间
      currentTime.value = formatTime(audioElement.currentTime);
      originalTime.value = audioElement.currentTime;
      progress.value = calculatePercentage(audioElement.duration, audioElement.currentTime)
      handleLyricProgress(currentTime.value)
    });
  }
});

// 处理歌词进度
function handleLyricProgress(currentTime: string) {
  if (lyrics.value.length > 0) {
    let number = 1
    lyrics.value.forEach((item) => {
      if (currentTime >= item.timestamp) {
        number += 1
      }
    })
    if ((number - 1) > 0 && number !== prevNumber.value) {
      prevNumber.value = number
      const lycDom = document.querySelector(".lyric-item")
      if (lycDom) {
        musicLyricTranslate.value = originalMusicLyricTranslate.value - lycDom.clientHeight * (number - 1)
      }
    }
  }
}

const downloadFile = throttle((url: string) => {
  if (timeoutId !== null) {
    clearTimeout(timeoutId);
  }
  showMessage("暂时无法自动下载歌曲，需要服务端配置，2秒后跳转页面，可手动下载", "success")
  timeoutId = setTimeout(() => {
    window.open(url, "_blank");
    timeoutId = null; // 清除计时器后重置 timeoutId
  }, 2000);
}, 500);
</script>

<style lang='scss' scoped>
@import "music";
</style>
